#ifdef WX_PRECOMP
#include "wx_pch.h"
#else
#include <wx/wx.h>
#endif //WX_PRECOMP

#include "base_parser.h"
#include <wx/xml/xml.h>

struct BaseParser::Item
{
  void* DataPtr;
  BaseExchanger* ExchangeClass;
  HandlerType Mode;
  Item()
    : DataPtr(0)
    , ExchangeClass(0)
    , Mode(None)
  {
  }
};

BaseParser::BaseParser()
{
}

BaseParser::~BaseParser()
{
  for (ParseMap::iterator i = Mapping.begin(); i != Mapping.end(); ++i)
  {
    delete (*i).second.ExchangeClass;
  }
  Mapping.clear();
}

bool BaseParser::ProcessRead(wxXmlNode* parent)
{
  for (wxXmlNode *child = parent->GetChildren(); child; child = child->GetNext())
  {
    wxString childName = child->GetName();
    ParseMap::const_iterator iter = Mapping.find(childName.MakeLower());
    if (iter == Mapping.end())
    {
      wxLogWarning(_("Unknow element '%s' in input XML"), child->GetName().c_str());
      continue;
    }

    const Item& data = (*iter).second;
    if (data.Mode == Read || data.Mode == ReadWrite)
    {
      if (!data.ExchangeClass)
      {
        wxLogError(_("Internal parcer error for property \"%s\""), (*iter).first.c_str());
        continue;
      }
      data.ExchangeClass->Read(child->GetNodeContent(), data.DataPtr);
    }
  }

  return OnParceComplete();
}

bool BaseParser::ProcessWrite(wxXmlNode* parent)
{
  for (ParseMap::const_iterator i = Mapping.begin(); i != Mapping.end(); ++i)
  {
    const Item& data = (*i).second;
    if (data.Mode == Write || data.Mode == ReadWrite)
    {
      data.ExchangeClass->Write((*i).first, data.DataPtr, parent);
    }
  }
  return true;
}

void BaseParser::SetHandler(const wxString& tagName, void* dataPointer, const BaseExchanger& parceFunction, const HandlerType& type)
{
  Item data;
  data.DataPtr = dataPointer;
  data.ExchangeClass = parceFunction.Clone();
  data.Mode = type;
  Mapping[tagName] = data;
}
